#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>

//int main()
//{
//    pid_t id = fork();
//    if(id == 0)
//    {
//        //child
//        int cnt = 5;
//        while(cnt)
//        {
//            printf("I am a child,pid:%d,cnt:%d\n",getpid(),cnt);
//            cnt--;
//        }
//        exit(5);//这里让子进程退出码为5
//    }
//    //father
//    int status = 0;
//    wait(&status);
//    printf("wait child success,exit code:%d,exit signal:%d\n",(status>>8)&0xff,status&0x7f);
//    return 0;
//}


void Worker(int cnt)    
{
    printf("I am a child ,pid:%d , cnt :%d\n",getpid(),cnt);
}

int main()
{
    pid_t id = fork();
    if(id == 0)
    {
        //child;
        int cnt = 5;
        while(cnt)
        {
            Worker(cnt);
            cnt--;
            sleep(2);
        }
        exit(0);
    }

    //father
    while(1)//非阻塞轮旋
    {        
        int status = 0;
        pid_t rid = waitpid(id, &status,WNOHANG); 
        if(rid>0)
        {
            //wait success,child quit now;
            printf("child quit success,exit code:%d,exit signal:%d\n",(status>>8)&0xff,status&0x7f);
            break;
        }
        else if(rid == 0) 
        {
            //wait success,but child not quit.
            printf("child is alive,wait agin,father do other thing....\n");
        }
        else 
        {
            //wait failed,child unknow
            printf("wait failed\n");
            break;
        }
        sleep(1);

    }
    return 0;
}





//void Worker(int number)
//{
//    int cnt = 10;
//    while(cnt)
//    {
//        printf("I am child process,pid:%d,ppid:%d,cnt:%d,number:%d\n",getpid(),getppid(),cnt,number);
//        sleep(1);
//        cnt--;
//    }
//    
//    //int *p = NULL;
//    //*p = 100;
//
//    //int a = 10;
//    //a/=0;
//}
//
//int main()
//{
//    int n = 10;
//    for(int i = 0; i<n;i++)
//    {
//        pid_t id = fork();
//        if(id==0)
//        {
//            Worker(i);
//            exit(i);
//        }
//        
//    }
//
//    //等待多个子进程
//    for(int i = 0;i<n;i++)
//    {
//        int status = 0;
//        //第一个参数pid>0,表示指定等待的进程， -1 表示等待任意一个退出的子进程
//        pid_t rid = waitpid(-1,&status,0);//可以定义数组保存多个子进程的pid
//        if(rid>0)
//        {
//            printf("wait child %d success,exit code:%d\n",rid,WEXITSTATUS(status));
//        }
//    }
//
//    return 0;
//}

//int main()
//{
//    pid_t id = fork();
//    if(id == 0)
//    {
//        //child
//        Worker();
//        exit(10);
//    }
//    else 
//    {
//        //father
//        sleep(5);//方便查看僵尸状态
//        printf("wait before\n");
//        //pid_t rid = wait(NULL);
//        
//        int status = 0;
//        pid_t rid = waitpid(id,&status,0);
//        //如果子进程根本没有退出，父进程必须在wait上进行阻塞等待，直到子进程僵尸，wait自动回收，返回
//        printf("wait after\n");
//        if(rid == id)
//        {
//            //我们不能对status整体使用，需要对二进制进行分析
//            //printf("wait success,pid:%d,rid:%d,status:%d,exit sig:%d,exit code:%d\n",getpid(),rid,status,status&0x7f,(status>>8)&0xff);
//            if(WIFEXITED(status))
//            {
//                printf("child process normal quit, exit code:%d \n",WIFEXITED(status));
//            }
//            else 
//            {
//                printf("child process quit except!\n");
//            }
//        }
//        sleep(5);
//    }
//    return 0;
//}

//int func()
//{
//    printf("call func function done\n");
//    return 11;
//    //任意地点调用exit,表示进程退出，不进行后续执行
//    //exit(21);
//    _exit(21);
//}
//
//
//int main()
//{
//    printf("you can see me!\n");
//    sleep(3);
//    exit(1);//exit,return进程结束也会刷新缓冲区，库函数
//    _exit(1);//系统调用，终止进程时候，不会自动刷新缓冲区
//    //func();
//
//    //printf("I am a process,pid:%d,ppid:%d\n",getpid(),getppid());
//    
//    //参数是进程的退出码，类似于main return n
//    //exit(12);
//    //_exit(12);
//    //1.main函数中进行直接return
//    //2.在其他函数中进行return，表示的是函数调用结束
//    //return 21;
//}
    printf("hello world\n");
